package com.yudean.esb.service.impl.erp;


import com.yudean.esb.dao.mds.MdsERPFinPerformanceDataDao;
import com.yudean.esb.domain.mds.MdsFinPerformanceData;
import com.yudean.esb.service.ERPFinPerforService;
import com.yudean.esb.security.SysAppUserService;
import com.yudean.esb.util.PageUtil;
import com.yudean.esb.util.StringUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jws.WebService;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.isEmpty;

@WebService(endpointInterface = "com.yudean.esb.service.ERPFinPerforService", serviceName = "ERPFinPerforServiceService",targetNamespace = "http://service.esb.yudean.com/")
@Service
@Scope("prototype")
public class ERPFinPerforServiceImpl implements ERPFinPerforService {
    private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ERPFinPerforServiceImpl.class);
    @Resource
    private SysAppUserService sysAppUserService;
    @Resource
    private MdsERPFinPerformanceDataDao mdsFinPerformanceDataDao;

    static int totalHypFinPerformanceDataCount = 0;

    static String perCompCode = "";
    static String perUserName = "";
    static String perPasswd = "";

    /**
     * 获得公司净利润
     * @param compCode        公司三字码
     * @param periodName      期间
     * @param performanceCode 指标代码
     * @param viewName        值类型
     * @param userName        用户名
     * @param passwd          密码
     * @return                根据公司三字码、期间，指标代码，用户账号、密码查询财务经营数据
     */
    @Override
    public String getFinPerformanceData(String compCode,
                                        String periodName,
                                        String performanceCode,
                                        String viewName,
                                        String userName,
                                        String passwd) {
        if ((!"".equals(userName) && perCompCode.equals(compCode) && perUserName.equals(userName) && perPasswd.equals(passwd))
                || hasPermission(compCode, userName, passwd)) {
            perCompCode = compCode;
            perUserName = userName;
            perPasswd = passwd;
        } else {
            return noPermission();
        }
        if (isEmpty(compCode)) {
            return noData();
        }
        logger.debug("getFinPerformanceData():reuqest-{compCode:{},periodName:{},performanceCode:{},viewName:{},userName:{}}",
                compCode, periodName, performanceCode, viewName, userName);

        List<MdsFinPerformanceData> mdsFinPerformanceDataList = mdsFinPerformanceDataDao.getFinPerformanceData(compCode, periodName, performanceCode, viewName);
        if (mdsFinPerformanceDataList == null || mdsFinPerformanceDataList.size() == 0) {
            return noData();
        }
        return wrapXML(mdsFinPerformanceDataList);
    }

    @Override
    public String getFinPerformanceDataByHYPCode(String hypCode,
                                                 String periodName,
                                                 String performanceCode,
                                                 String viewName,
                                                 String userName,
                                                 String passwd) {
        if (hasPermission(hypCode, userName, passwd)) {
            perCompCode = hypCode;
            perUserName = userName;
            perPasswd = passwd;
        } else {
            return noPermission();
        }
        if (isEmpty(hypCode)) {
            return noData();
        }
        logger.debug("getFinPerformanceData():reuqest-{hypCode:{},periodName:{},performanceCode:{},viewName:{},userName:{}}",
                hypCode, periodName, performanceCode, viewName, userName);

        List<MdsFinPerformanceData> mdsFinPerformanceDataList = mdsFinPerformanceDataDao.getFinPerformanceDataByHYPCode(hypCode, periodName, performanceCode, viewName);
        if (mdsFinPerformanceDataList == null || mdsFinPerformanceDataList.size() == 0) {
            return noData();
        }
        return wrapXML(mdsFinPerformanceDataList);
    }

    /**
     * @param periodName    期间
     * @param userName      用户账号
     * @param passwd        用户密码
     * @return              根据期间，用户账号、密码查询所有源数据‘HYP’的财务经营数据
     */
    @Override
    public String getHypFinPerformanceDataByPeriodName(String periodName, String userName, String passwd) {
        if ((!"".equals(userName) && perCompCode.equals("YDZ") && perUserName.equals(userName) && perPasswd.equals(passwd))
                || hasPermission("YDZ", userName, passwd)) {
            perCompCode = "YDZ";
            perUserName = userName;
            perPasswd = passwd;
        } else {
            return noPermission();
        }
        logger.debug("getFinPerformanceData():reuqest-{,periodName:{},userName:{}}", periodName, userName);

        List<MdsFinPerformanceData> mdsFinPerformanceDataList = mdsFinPerformanceDataDao.getHypFinPerformanceDataByPeriodName(periodName);
        if (mdsFinPerformanceDataList == null || mdsFinPerformanceDataList.size() == 0) {
            return noData();
        }
        return wrapXML(mdsFinPerformanceDataList);
    }

    /**
     * @param periodName    期间
     * @param pageNo        页码
     * @param pageSize      页面大小
     * @param userName      用户账号
     * @param passwd        用户密码
     * @return              根据期间，页码，页面大小，用户账号、密码查询所有源数据‘HYP’的财务经营数据（分页方式）
     */
    @Override
    public String getHypFinPerformanceDataByPeriodNamePageSize(String periodName, String pageNo, String pageSize, String userName, String passwd) {
        if ((!"".equals(userName) && perCompCode.equals("YDZ") && perUserName.equals(userName) && perPasswd.equals(passwd))
                || hasPermission("YDZ", userName, passwd)) {
            perCompCode = "YDZ";
            perUserName = userName;
            perPasswd = passwd;
        } else {
            return noPermission();
        }
        logger.debug("getHypFinPerformanceDataByPeriodNamePageSize():reuqest-{,periodName:{},userName:{}}", periodName, userName);
        try {

            int pageNoInt =   PageUtil.handlePageNo(pageNo).intValue();
            int pageSizeInt = PageUtil.handlePageSize(pageSize).intValue();

            //查询第一页数据时候初始化总量
            if (pageNoInt == 1) {
                totalHypFinPerformanceDataCount = mdsFinPerformanceDataDao.getAllHypFinPerformanceDataByPeriodNameCount(periodName);
            }
            int total = totalHypFinPerformanceDataCount <= 0 ? mdsFinPerformanceDataDao.getAllHypFinPerformanceDataByPeriodNameCount(periodName) : totalHypFinPerformanceDataCount;

            int startRow = (pageNoInt - 1) * pageSizeInt;
            int endRow = startRow + pageSizeInt;

            List<MdsFinPerformanceData> mdsFinPerformanceDataList = mdsFinPerformanceDataDao.getHypFinPerformanceDataByPeriodNamePageSize(periodName, startRow, endRow);
            if (mdsFinPerformanceDataList == null || mdsFinPerformanceDataList.size() == 0) {
                return noData();
            }
            return wrapXML(mdsFinPerformanceDataList, total, pageNoInt, pageSizeInt);
        } catch (Exception e) {
            logger.error("getHypFinPerformanceDataByPeriodNamePageSize():error-{}", e.getMessage());
            return errorMsg("getHypFinPerformanceDataByPeriodNamePageSize", e.getMessage());
        }

    }


    /**
     * 返回空数据的时候的信息
     *
     * @return
     */
    private static String noData() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务经营数据</name><type>发布服务</type><datalist><!--查无数据--></datalist></service>";
    }

    /**
     * 返回查询出错信息
     *
     * @param msg
     * @return
     */
    private String errorMsg(String serviceName, String msg) {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>" + serviceName + "</name><type>发布服务</type><datalist><!--error Message:" + msg + "--></datalist></service>";
    }

    /**
     * 验证是否拥有访问的权限
     *
     * @param compCode
     * @param userName
     * @param passwd
     * @return
     */
    private boolean hasPermission(String compCode, String userName,
                                  String passwd) {
        return sysAppUserService.hasPermit(compCode, userName, passwd);
    }

    /**
     * 权限认证失败返回的信息
     *
     * @return
     */
    private static String noPermission() {
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><service><name>ERP财务经营数据</name><type>发布服务</type><datalist><!--权限认证失败--></datalist></service>";
    }

    /**
     * 对象封装成XML字符串
     *
     * @param list
     * @return
     */
    private String wrapXML(List<MdsFinPerformanceData> list) {
        Document root = null;
        root = DocumentHelper.createDocument();
        Element element = root.addElement("service");
        element.addElement("name").setText("ESB:ERPFinPerforService");
        element.addElement("type").setText("发布服务");
        Element datalist = element.addElement("datalist");
        for (MdsFinPerformanceData mdsFinPerformanceData : list) {
            Element data = datalist.addElement("data");
            data.addElement("compCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getCompCode()));
            data.addElement("hypCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getHypCode()));
            data.addElement("periodName").setText(StringUtil.convertToString(mdsFinPerformanceData.getPeriodName()));

            data.addElement("performanceCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getPerformanceCode()));
            data.addElement("performanceDesc").setText(StringUtil.convertToString(mdsFinPerformanceData.getPerformanceDesc()));
            data.addElement("viewName").setText(StringUtil.convertToString(mdsFinPerformanceData.getViewName()));
            data.addElement("dataValue").setText(StringUtil.convertToString(mdsFinPerformanceData.getDataValue()));
            data.addElement("dataSource").setText(StringUtil.convertToString(mdsFinPerformanceData.getDataSource()));
            data.addElement("creationDate").setText(StringUtil.date2String(mdsFinPerformanceData.getCreationDate()));
            data.addElement("createdBy").setText(StringUtil.convertToString(mdsFinPerformanceData.getCreatedBy()));
            data.addElement("lastUpdateDate").setText(StringUtil.date2String(mdsFinPerformanceData.getLastUpdateDate()));
            data.addElement("lastUpdatedBy").setText(StringUtil.convertToString(mdsFinPerformanceData.getLastUpdatedBy()));
            data.addElement("lastUpdateLogin").setText(StringUtil.convertToString(mdsFinPerformanceData.getLastUpdateLogin()));
            data.addElement("attributeCategory").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttributeCategory()));

            data.addElement("attribute1").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute1()));
            data.addElement("attribute2").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute2()));
            data.addElement("attribute3").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute3()));
            data.addElement("attribute4").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute4()));
            data.addElement("attribute5").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute5()));
            data.addElement("attribute6").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute6()));
            data.addElement("attribute7").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute7()));
            data.addElement("attribute8").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute8()));
            data.addElement("attribute9").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute9()));
            data.addElement("attribute10").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute10()));
        }
        return root.asXML();
    }


    private String wrapXML(List<MdsFinPerformanceData> list, int total, int pageNo, int pageSize) {
        Document root = null;
        root = DocumentHelper.createDocument();
        Element element = root.addElement("service");
        element.addElement("name").setText("ESB:ERPFinPerforService");
        element.addElement("type").setText("发布服务");
        element.addElement("total").setText(StringUtil.convertToString(total));
        element.addElement("pageNo").setText(StringUtil.convertToString(pageNo));
        element.addElement("pageSize").setText(StringUtil.convertToString(pageSize));
        Element datalist = element.addElement("datalist");
        for (MdsFinPerformanceData mdsFinPerformanceData : list) {
            Element data = datalist.addElement("data");
            data.addElement("compCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getCompCode()));
            data.addElement("hypCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getHypCode()));
            data.addElement("periodName").setText(StringUtil.convertToString(mdsFinPerformanceData.getPeriodName()));

            data.addElement("performanceCode").setText(StringUtil.convertToString(mdsFinPerformanceData.getPerformanceCode()));
            data.addElement("performanceDesc").setText(StringUtil.convertToString(mdsFinPerformanceData.getPerformanceDesc()));
            data.addElement("viewName").setText(StringUtil.convertToString(mdsFinPerformanceData.getViewName()));
            data.addElement("dataValue").setText(StringUtil.convertToString(mdsFinPerformanceData.getDataValue()));
            data.addElement("dataSource").setText(StringUtil.convertToString(mdsFinPerformanceData.getDataSource()));
            data.addElement("creationDate").setText(StringUtil.date2String(mdsFinPerformanceData.getCreationDate()));
            data.addElement("createdBy").setText(StringUtil.convertToString(mdsFinPerformanceData.getCreatedBy()));
            data.addElement("lastUpdateDate").setText(StringUtil.date2String(mdsFinPerformanceData.getLastUpdateDate()));
            data.addElement("lastUpdatedBy").setText(StringUtil.convertToString(mdsFinPerformanceData.getLastUpdatedBy()));
            data.addElement("lastUpdateLogin").setText(StringUtil.convertToString(mdsFinPerformanceData.getLastUpdateLogin()));
            data.addElement("attributeCategory").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttributeCategory()));

            data.addElement("attribute1").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute1()));
            data.addElement("attribute2").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute2()));
            data.addElement("attribute3").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute3()));
            data.addElement("attribute4").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute4()));
            data.addElement("attribute5").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute5()));
            data.addElement("attribute6").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute6()));
            data.addElement("attribute7").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute7()));
            data.addElement("attribute8").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute8()));
            data.addElement("attribute9").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute9()));
            data.addElement("attribute10").setText(StringUtil.convertToString(mdsFinPerformanceData.getAttribute10()));
        }
        return root.asXML();
    }


}
